Advanced Spatial Methods I: do-pair-share solution

Peter Ganong and Maggie Shi

January 21, 2026

Do-pair-share: starting point

Do-pair-share: starter code

import geopandas as gpd
import matplotlib.pyplot as plt
from matplotlib import patheffects as pe # used later to format text
import shapely

# load geodata
iso_gdf = gpd.read_file('data/derived-data/Independent_System_Operator.geojson')
us_states_gdf = gpd.read_file('data/derived-data/lower_48_states.geojson')
us_states_gdf.crs = iso_gdf.crs


# initiate figure
fig, ax = plt.subplots(figsize=(6, 6), dpi=1000)

# plot ISOs and boundaries
iso_gdf.plot(ax = ax, facecolor = 'blue', alpha = 0.3).set_axis_off()
iso_gdf.boundary.plot(ax=ax, color="navy", alpha = 0.5, linewidth=0.6)

# generate centroids and plot
iso_centroids = iso_gdf.centroid
iso_centroids.plot(ax=ax, marker="o",color="darkgreen", markersize=30,zorder=3)

# iterate through labels 
for _, row in iso_gdf.iterrows():
    ax.text(x=row.geometry.centroid.x, y=row.geometry.centroid.y, ha="left", va="center",
        s=row["NAME"], 
        fontsize=5, zorder=3,
        path_effects=[
            pe.Stroke(linewidth=2, foreground="white"),  # white halo
            pe.Normal(),]
    )

# plot remaining states underneath
us_states_gdf.plot(ax= ax, color= 'lightgray', edgecolor='none', zorder= 2, alpha= 0.3)
plt.title("Independent Systems Operators in the Lower 48 States")
plt.show()

Do-pair-share: end goal

Do-pair-share: solution

fig, ax = plt.subplots(figsize=(6, 6), dpi=1000)

# plot the ISO polygons with alpha = 0.4 transparency
iso_gdf.plot(ax = ax, facecolor = 'blue', alpha = 0.1).set_axis_off()

# add boundaries
iso_gdf.boundary.plot(ax=ax, color="navy", alpha = 0.5, linewidth=0.6)

# subset to MISO
miso_gdf = iso_gdf[iso_gdf["NAME"] == "Midcontinent Independent Transmission System Operator, Inc.."]

# plot MISO centroid
miso_gdf.centroid.plot(ax=ax, marker="o",color="darkgreen", markersize=30,zorder=4)

# plot MISO on top 
miso_gdf.plot(ax= ax, color= 'firebrick', edgecolor='none', zorder= 3, alpha= 0.8)

# format and place labels
for _, row in miso_gdf.iterrows():
    ax.text(x=row.geometry.centroid.x, y=row.geometry.centroid.y, ha="left", va="center",
        s=row["NAME"], 
        fontsize=5, zorder=3,
        path_effects=[
            pe.Stroke(linewidth=2, foreground="white"),  # white halo
            pe.Normal(),]
    )

# plotting the non-ISO areas on top but transparent (utilizing alpha)
us_states_gdf.plot(ax= ax, color= 'lightgray', edgecolor='none', zorder= 2, alpha= 0.3)
plt.title("MISO and Other ISOs in the Lower 48 States")
plt.show()